package com.xuecheng.ucenter.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.ucenter.mapper.XcMenuMapper;
import com.xuecheng.ucenter.mapper.XcPermissionMapper;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.model.po.XcMenu;
import com.xuecheng.ucenter.model.po.XcUser;
import com.xuecheng.ucenter.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ws
 * Date: 2024-07-15
 * Time: 23:48
 */

@Slf4j
@Component
public class UserServiceImpl implements UserDetailsService {

    @Resource
    XcMenuMapper xcMenuMapper;

    @Resource
    ApplicationContext applicationContext;

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        AuthParamsDto authParamsDto = null;
        try {
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class);
        } catch (Exception e) {
            throw new RuntimeException("请求参数不符合要求");
        }
        // 认证类型，即 Bean 的名称
        String beanName = authParamsDto.getAuthType() + "_authservice";
        AuthService authService = applicationContext.getBean(beanName, AuthService.class);
        // 调用认证方法
        XcUserExt xcUserExt = authService.execute(authParamsDto);

        // 用户存在，返回 UserDetails 对象，spring security 会自动比对密码
        // 将用户信息转为Json
        // 最终根据 userDetails 这个对象生成令牌
        UserDetails userDetails = getUserPrincipal(xcUserExt);

        return userDetails;
    }

    /**
     * @param user 用户id，主键
     * @return com.xuecheng.ucenter.model.po.XcUser 用户信息
     * @description 查询用户信息
     */
    public UserDetails getUserPrincipal(XcUserExt user) {
        //用户权限,如果不加报 Cannot pass a null GrantedAuthority collection
        String[] authorities = {"test"};
        // 更具用户的 id 查询权限
        List<XcMenu> xcMenus = xcMenuMapper.selectPermissionByUserId(user.getId());
        if (!CollectionUtils.isEmpty(xcMenus)) {
            authorities = xcMenus.stream().map(XcMenu::getCode).toArray(String[]::new);
        }
        String password = user.getPassword();
        //为了安全在令牌中不放密码
        user.setPassword(null);
        //将user对象转json
        String userString = JSON.toJSONString(user);
        //创建UserDetails对象
        UserDetails userDetails = User.withUsername(userString).password(password).authorities(authorities).build();
        return userDetails;
    }

}
